package cate.game.pvp.ladder;

import cate.common.rpc.path.RpcLadderPath;
import cate.common.table.d.*;
import cate.game.framework.GameException;
import cate.game.play.proce.play.PlayPO;
import cate.game.play.vo.ReplayUtils;
import cate.game.pvp.ladder.common.*;
import cate.game.res.MixRes;
import cate.game.role.Role;
import cate.game.role.farm.AbstractFarmFTC;
import cate.game.role.pvp.PvpRecord;
import cate.game.pvp.ladder.msg.LadderChallengeResp;
import cp.solution.manage.api.open.replay.ReplaySaveReq;
import cp.solution.manage.api.open.replay.ReplaySaveResp;
import easy.java.practice.errorcode.EcResult;
import lombok.extern.slf4j.Slf4j;

import static cate.common.table.d.GDLadder.REPLAY_KEEP_TIME;

@Slf4j
public class LadderFTC extends AbstractFarmFTC<RoleLadder> {

    private final LadderCompetition competition;

    public LadderFTC(LadderCompetition competition) {
        this.competition = competition;
    }

    @Override
    protected RoleLadder po(Role role) {
        return role.getPvp().ladder;
    }

    @Override
    public void handleResult(Role role, PlayPO playPO) {
        super.handleResult(role, playPO);
        try {
            log.info("天梯赛FTC处理战斗结果");

            ReplaySaveReq saveReq = ReplayUtils.toReplaySaveReq(playPO, role.getGame().time.now() + REPLAY_KEEP_TIME);
            EcResult<ReplaySaveResp> rsp = role.getGame().openApi().saveReplay(saveReq);
            if (!rsp.ok()) {
                log.error("天梯赛保存录像错误 {}", rsp.message);
            }
            role.getGame().videoHall.addVideo(GDVideoHall.Group.LADDER_RACE, playPO);

            boolean isWin = playPO.winner == GDFight.Team.A;

            PvpRecord record = new PvpRecord();
            record.winner = playPO.winner;
            record.snapshotA = competition.getSelfSnapshot();
            record.snapshotB = competition.getOppoSnapshot();
            record.valueA = competition.getSelfRankOld();// 个人原排名
            record.valueChangeA = 0;// 个人排名变化
            record.valueB = competition.getOppoRankOld();// 对手原排名
            record.valueChangeB = 0;// 对手排名变化

            record.replayUid = String.valueOf(rsp.data.getId());
            record.recordTime = playPO.startTime;

            MixRes reward = new MixRes(role.getGame().table.ladder.base.getReward(isWin));



            if (isWin) {
                //战胜更高名次的对手后，玩家将与当前名次的排名对调
                if (record.valueA == 0 || record.valueA > record.valueB) {
                    record.valueA = competition.getOppoRankOld();
                    int value = competition.getSelfRankOld();
                    if (value == 0) {
                        //榜单外
                        value = GDLadder.RANK_SIZE + 1;
                    }
                    record.valueChangeA = value - record.valueA;
                    record.valueB = competition.getSelfRankOld();
                    record.valueChangeB = competition.getOppoRankOld() - value;
                    //更新榜单
                    LadderRankUpdateQuery query = new LadderRankUpdateQuery();
                    query.srvId = role.getBase().srvId;
                    query.power = role.getBase().power;
                    query.name = role.getBase().name;
                    query.oppoRank = competition.getSelfRankOld();
                    query.selfId = role.getUid();
                    query.oppoId = competition.getOppoSnapshot().uid;
                    query.selfRank = competition.getOppoRankOld();
                    query.selfPs = competition.getSelfPsDef();
                    query.level = role.getBase().level;
                    LadderRankUpdateResult result = role.getGame().pvp.ladder.updateRankList(query);
                    if(!result.ok()) {
                        throw new GameException().content("更新天梯赛榜单失败:"+result.reason()).s();
                    }
                }
                role.getRes().hoard.addition.addTask(GDHoardTask.LADDER);
            }
            //战报增加
            LadderReport ladderReport = new LadderReport();
            ladderReport.winner = playPO.winner;
            ladderReport.snapshotA = competition.getSelfSnapshot();
            ladderReport.snapshotB = competition.getOppoSnapshot();
            ladderReport.rankA = record.valueA;
            ladderReport.rankB = record.valueB;
            ladderReport.replayUid = String.valueOf(rsp.data.getId());
            ladderReport.recordTime = playPO.startTime;
            if (competition.isRobot()){
                ladderReport.snapshotB.base.uid = competition.getOppoSnapshot().uid;
            }
            role.getPvp().ladder.addReport(ladderReport);
            if (!competition.isRobot()) {
                String oppoRoleId = competition.getOppoSnapshot().uid;
                int oppoSrvId = competition.getOppoSnapshot().base.srvId;
                LadderReportQuery query = new LadderReportQuery();
                query.oppoRoleId = oppoRoleId;
                query.report = ladderReport;
                role.getGame().rpcSend().fireAndForgetGame(RpcLadderPath.PLAY_REPORT_G2G, oppoSrvId, query);
            }

            role.getPvp().ladder.rank = (int) record.valueA;
            role.log.setOperation(GDOperation.LADDER_CHALLENGE_RWD);
            reward.add(role, true, GDOperation.LADDER_CHALLENGE_RWD);
            role.log.clearOperation();

            //添加大神风采
            if ((record.valueA < 100 && record.valueA > 0) || (record.valueB < 100 && record.valueB > 0)) {
                LadderReportQuery query = new LadderReportQuery();
                query.oppoRoleId = role.getUid();
                query.report = ladderReport;
                role.getGame().pvp.ladder.addRecord(query);
            }

            //天梯赛解锁对手
            LadderLockOppoResult r_lck = role.getGame().pvp.ladder.unLockOpponent(new LadderLockOppoQuery(competition.getOppoSnapshot().uid,role.getUid()));
            if(!r_lck.ok()) {
                log.info("解锁对手阵容失败:"+r_lck.reason()+"，请刷新后重试");
            }
            role.getPvp().ladder.noticeUpdate();

            LadderChallengeResp resp = new LadderChallengeResp(record, reward);
            resp.sendNow(role);
            if (isWin) {
                role.getHistory().action.ladderWin();
            }
        } catch (Throwable e) {
            log.error("天梯赛FTC异常", e);
        }
    }
}
